package edu.gzhu.guli.back.service.subject;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.modelmapper.ModelMapper;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import edu.gzhu.guli.back.service.course.CourseReadDto;
import edu.gzhu.guli.core.common.ApplicationResult;
import edu.gzhu.guli.core.entity.Course;
import edu.gzhu.guli.core.entity.Course_;
import edu.gzhu.guli.core.entity.Subject;
import edu.gzhu.guli.core.entity.Subject_;
import edu.gzhu.guli.core.repository.CourseRepository;
import edu.gzhu.guli.core.repository.SubjectRepository;
import lombok.AllArgsConstructor;

@Service
@AllArgsConstructor
public class SubjectService {

  final SubjectRepository subjectRepository;
  final CourseRepository courseRepository;
  final ModelMapper modelMapper;

  // 获取全部主题
  public ApplicationResult<List<SubjectCascadeDto>> loadAll() {
    List<Subject> tops = subjectRepository
        .findAll(builder -> builder.andEquals(Subject_.PID, 0L).build());
    List<SubjectCascadeDto> data = new ArrayList<>();
    for (Subject top : tops) {
      SubjectCascadeDto topDto = SubjectCascadeDto.father(top);
      List<Subject> children = subjectRepository
          .findAll(builder -> builder.andEquals(Subject_.PID, top.getId()).build());
      for (Subject child : children) {
        SubjectCascadeDto childDto = SubjectCascadeDto.child(child);
        topDto.getChildren().add(childDto);
      }
      data.add(topDto);
    }
    return ApplicationResult.succese(data);
  }

  // 获取主题课程
  public ApplicationResult<Page<CourseReadDto>> loadDetails(Long subjectId, int page, int size) {
    Optional<Subject> check = subjectRepository.findById(subjectId);
    if (!check.isPresent())
      return ApplicationResult.failure("未找到相应的主题");
    Subject subject = check.get();
    boolean isTop = subject.getPid().equals(0L);
    Page<Course> payload = null;
    if (isTop) {
      payload = courseRepository.findAll(builder -> builder.andEquals(Course_.TOP_SUBJECT, subjectId).build(),
          PageRequest.of(page, size));
    } else {
      payload = courseRepository.findAll(builder -> builder.andEquals(Course_.SUBJECT, subjectId).build(),
          PageRequest.of(page, size));
    }
    Page<CourseReadDto> data = payload.map(it -> modelMapper.map(it, CourseReadDto.class));
    return ApplicationResult.succese(data);
  }

  // 新建主题
  public ApplicationResult<SubjectReadDto> create(SubjectCreateOrEditDto dto) {
    Optional<Subject> check = subjectRepository.findByName(dto.getName());
    if (check.isPresent())
      return ApplicationResult.failure("名为：" + dto.getName() + "的标签已存在");
    Subject subject = modelMapper.map(dto, Subject.class);
    subject = subjectRepository.save(subject);
    SubjectReadDto data = modelMapper.map(subject, SubjectReadDto.class);
    return ApplicationResult.succese(data);
  }

  // 修改主题
  public ApplicationResult<SubjectReadDto> edit(Long subjectId, SubjectCreateOrEditDto dto) {
    Optional<Subject> check = subjectRepository.findById(subjectId);
    if (!check.isPresent())
      return ApplicationResult.failure("未找到目标主题");
    Subject subject = check.get();
    check = subjectRepository.findOne(builder -> {
      return builder.andEquals(Subject_.NAME, dto.getName())
          .andNotEquals(Subject_.ID, subjectId).build();
    });
    if (check.isPresent())
      return ApplicationResult.failure("名为：" + dto.getName() + "的标签已存在");
    modelMapper.map(dto, subject);
    subject = subjectRepository.save(subject);
    SubjectReadDto data = modelMapper.map(subject, SubjectReadDto.class);
    return ApplicationResult.succese(data);
  }

  // 在主题下添加课程
  public ApplicationResult<Object> addCourseToSubject(Long subjectId, Long courseId) {
    Optional<Subject> checkSubject = subjectRepository.findById(subjectId);
    if (!checkSubject.isPresent())
      return ApplicationResult.failure("未找到目标主题");
    Subject subject = checkSubject.get();

    Optional<Course> checkCourse = courseRepository.findById(courseId);
    if (!checkCourse.isPresent())
      return ApplicationResult.failure("未找到目标课程");
    Course course = checkCourse.get();

    long pid = subject.getPid();
    // 最高级
    if (pid == 0) {
      course.setTopSubject(subject);
    } else {
      Subject topSubject = subjectRepository.getById(pid);
      course.setTopSubject(topSubject);
      course.setSubject(subject);
    }

    course = courseRepository.save(course);
    return ApplicationResult.succese();
  }

  // todo: 删除业务逻辑
  public ApplicationResult<Object> delete(Long subjectId) {
    Optional<Subject> check = subjectRepository.findById(subjectId);
    if (!check.isPresent())
      return ApplicationResult.failure("未找到目标主题");
    subjectRepository.delete(check.get());
    return ApplicationResult.succese();
  }

}
